package org.study.redis.api.util.jedis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.StreamEntryID;
import redis.clients.jedis.params.*;
import redis.clients.jedis.resps.*;

import java.util.List;
import java.util.Map;

/**
 * Redis 操作工具类：Stream
 * 参考 {@link redis.clients.jedis.commands.StreamCommands}
 *
 * @author doveylovey
 * @email 1135782208@qq.com
 * @date 2022年04月23日
 */
public class RedisStreamUtils {
    private RedisStreamUtils() {
        throw new AssertionError("不能实例化 RedisStreamUtils 工具类");
    }

    /**
     * 命令格式：XADD key ID field string [field string ...]
     */
    public static StreamEntryID xadd(String key, StreamEntryID id, Map<String, String> hash) {
        StreamEntryID xadd = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xadd = jedis.xadd(key, id, hash);
        }
        return xadd;
    }

    public static StreamEntryID xadd(String key, XAddParams params, Map<String, String> hash) {
        StreamEntryID xadd = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xadd = jedis.xadd(key, params, hash);
        }
        return xadd;
    }

    /**
     * 命令格式：XLEN key
     */
    public static long xlen(String key) {
        long xlen;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xlen = jedis.xlen(key);
        }
        return xlen;
    }

    /**
     * 命令格式：XRANGE key start end
     */
    public static List<StreamEntry> xrange(String key, StreamEntryID start, StreamEntryID end) {
        List<StreamEntry> xrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrange = jedis.xrange(key, start, end);
        }
        return xrange;
    }

    /**
     * 命令格式：XRANGE key start end COUNT count
     */
    public static List<StreamEntry> xrange(String key, StreamEntryID start, StreamEntryID end, int count) {
        List<StreamEntry> xrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrange = jedis.xrange(key, start, end, count);
        }
        return xrange;
    }

    /**
     * 命令格式：XREVRANGE key end start
     */
    public static List<StreamEntry> xrevrange(String key, StreamEntryID end, StreamEntryID start) {
        List<StreamEntry> xrevrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrevrange = jedis.xrevrange(key, end, start);
        }
        return xrevrange;
    }

    /**
     * 命令格式：XREVRANGE key end start COUNT count
     */
    public static List<StreamEntry> xrevrange(String key, StreamEntryID end, StreamEntryID start, int count) {
        List<StreamEntry> xrevrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrevrange = jedis.xrevrange(key, end, start, count);
        }
        return xrevrange;
    }

    public static List<StreamEntry> xrange(String key, String start, String end) {
        List<StreamEntry> xrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrange = jedis.xrange(key, start, end);
        }
        return xrange;
    }

    public static List<StreamEntry> xrange(String key, String start, String end, int count) {
        List<StreamEntry> xrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrange = jedis.xrange(key, start, end, count);
        }
        return xrange;
    }

    public static List<StreamEntry> xrevrange(String key, String end, String start) {
        List<StreamEntry> xrevrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrevrange = jedis.xrevrange(key, end, start);
        }
        return xrevrange;
    }

    public static List<StreamEntry> xrevrange(String key, String end, String start, int count) {
        List<StreamEntry> xrevrange = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xrevrange = jedis.xrevrange(key, end, start, count);
        }
        return xrevrange;
    }

    /**
     * 命令格式：XACK key group ID [ID ...]
     */
    public static long xack(String key, String group, StreamEntryID... ids) {
        long xack;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xack = jedis.xack(key, group, ids);
        }
        return xack;
    }

    /**
     * 命令格式：XGROUP CREATE <key> <groupname> <id or $>
     */
    public static String xgroupCreate(String key, String groupname, StreamEntryID id, boolean makeStream) {
        String xgroupCreate = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xgroupCreate = jedis.xgroupCreate(key, groupname, id, makeStream);
        }
        return xgroupCreate;
    }

    /**
     * 命令格式：XGROUP SETID <key> <groupname> <id or $>
     */
    public static String xgroupSetID(String key, String groupname, StreamEntryID id) {
        String xgroupSetID = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xgroupSetID = jedis.xgroupSetID(key, groupname, id);
        }
        return xgroupSetID;
    }

    /**
     * 命令格式：XGROUP DESTROY <key> <groupname>
     */
    public static long xgroupDestroy(String key, String groupname) {
        long xgroupDestroy;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xgroupDestroy = jedis.xgroupDestroy(key, groupname);
        }
        return xgroupDestroy;
    }

    /**
     * 命令格式：XGROUP DELCONSUMER <key> <groupname> <consumername>
     */
    public static long xgroupDelConsumer(String key, String groupname, String consumername) {
        long xgroupDelConsumer;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xgroupDelConsumer = jedis.xgroupDelConsumer(key, groupname, consumername);
        }
        return xgroupDelConsumer;
    }

    /**
     * 命令格式：XPENDING key group
     */
    public static StreamPendingSummary xpending(String key, String groupname) {
        StreamPendingSummary xpending = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xpending = jedis.xpending(key, groupname);
        }
        return xpending;
    }

    /**
     * 命令格式：XPENDING key group [[IDLE min-idle-time] start end count [consumer]]
     */
    public static List<StreamPendingEntry> xpending(String key, String groupname, XPendingParams params) {
        List<StreamPendingEntry> xpending = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xpending = jedis.xpending(key, groupname, params);
        }
        return xpending;
    }

    /**
     * 命令格式：XDEL key ID [ID ...]
     */
    public static long xdel(String key, StreamEntryID... ids) {
        long xdel;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xdel = jedis.xdel(key, ids);
        }
        return xdel;
    }

    /**
     * 命令格式：XTRIM key MAXLEN [~] count
     */
    public static long xtrim(String key, long maxLen, boolean approximate) {
        long xtrim;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xtrim = jedis.xtrim(key, maxLen, approximate);
        }
        return xtrim;
    }

    /**
     * 命令格式：XTRIM key MAXLEN|MINID [=|~] threshold [LIMIT count]
     */
    public static long xtrim(String key, XTrimParams params) {
        long xtrim;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xtrim = jedis.xtrim(key, params);
        }
        return xtrim;
    }

    /**
     * 命令格式：XCLAIM <key> <group> <consumer> <min-idle-time> <ID-1> ... <ID-N>
     * [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
     * [FORCE]
     */
    public static List<StreamEntry> xclaim(String key, String group, String consumername, long minIdleTime, XClaimParams params, StreamEntryID... ids) {
        List<StreamEntry> xclaim = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xclaim = jedis.xclaim(key, group, consumername, minIdleTime, params, ids);
        }
        return xclaim;
    }

    /**
     * 命令格式：XCLAIM <key> <group> <consumer> <min-idle-time> <ID-1> ... <ID-N>
     * [IDLE <milliseconds>] [TIME <mstime>] [RETRYCOUNT <count>]
     * [FORCE] JUSTID
     */
    public static List<StreamEntryID> xclaimJustId(String key, String group, String consumername, long minIdleTime, XClaimParams params, StreamEntryID... ids) {
        List<StreamEntryID> xclaimJustId = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xclaimJustId = jedis.xclaimJustId(key, group, consumername, minIdleTime, params, ids);
        }
        return xclaimJustId;
    }

    /**
     * 命令格式：XAUTOCLAIM key group consumer min-idle-time start [COUNT count]
     */
    public static Map.Entry<StreamEntryID, List<StreamEntry>> xautoclaim(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) {
        Map.Entry<StreamEntryID, List<StreamEntry>> xautoclaim = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xautoclaim = jedis.xautoclaim(key, group, consumerName, minIdleTime, start, params);
        }
        return xautoclaim;
    }

    /**
     * 命令格式：XAUTOCLAIM key group consumer min-idle-time start [COUNT count] JUSTID
     */
    public static Map.Entry<StreamEntryID, List<StreamEntryID>> xautoclaimJustId(String key, String group, String consumerName, long minIdleTime, StreamEntryID start, XAutoClaimParams params) {
        Map.Entry<StreamEntryID, List<StreamEntryID>> xautoclaimJustId = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xautoclaimJustId = jedis.xautoclaimJustId(key, group, consumerName, minIdleTime, start, params);
        }
        return xautoclaimJustId;
    }

    public static StreamInfo xinfoStream(String key) {
        StreamInfo xinfoStream = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xinfoStream = jedis.xinfoStream(key);
        }
        return xinfoStream;
    }

    public static StreamFullInfo xinfoStreamFull(String key) {
        StreamFullInfo xinfoStreamFull = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xinfoStreamFull = jedis.xinfoStreamFull(key);
        }
        return xinfoStreamFull;
    }

    public static StreamFullInfo xinfoStreamFull(String key, int count) {
        StreamFullInfo xinfoStreamFull = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xinfoStreamFull = jedis.xinfoStreamFull(key, count);
        }
        return xinfoStreamFull;
    }

    public static List<StreamGroupInfo> xinfoGroups(String key) {
        List<StreamGroupInfo> xinfoGroups = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xinfoGroups = jedis.xinfoGroups(key);
        }
        return xinfoGroups;
    }

    public static List<StreamConsumersInfo> xinfoConsumers(String key, String group) {
        List<StreamConsumersInfo> xinfoConsumers = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xinfoConsumers = jedis.xinfoConsumers(key, group);
        }
        return xinfoConsumers;
    }

    /**
     * 命令格式：XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
     */
    public static List<Map.Entry<String, List<StreamEntry>>> xread(XReadParams xReadParams, Map<String, StreamEntryID> streams) {
        List<Map.Entry<String, List<StreamEntry>>> xread = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xread = jedis.xread(xReadParams, streams);
        }
        return xread;
    }

    /**
     * 命令格式：XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
     */
    public static List<Map.Entry<String, List<StreamEntry>>> xreadGroup(String groupname, String consumer, XReadGroupParams xReadGroupParams, Map<String, StreamEntryID> streams) {
        List<Map.Entry<String, List<StreamEntry>>> xreadGroup = null;
        try (Jedis jedis = SysJedisPool.getResource()) {
            xreadGroup = jedis.xreadGroup(groupname, consumer, xReadGroupParams, streams);
        }
        return xreadGroup;
    }
}
